﻿using AudioStudio;
using com.youzu.warh.protocol;
using DestroyIt;
using DG.Tweening;
using DG.Tweening.Core;
using DG.Tweening.Plugins.Options;
using LogSystem;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using Yoozoo.Core.Common;
using Yoozoo.Gameplay.City;
using Yoozoo.Gameplay.Liberty.Pool;
using Yoozoo.Gta.Common;
using Yoozoo.Mars.Got;
using Random = UnityEngine.Random;

namespace Yoozoo.Gameplay.Liberty.AI
{
    public class BattleAgent : MonoBehaviour, IHittable
    {
        // 击杀回调
        public static Action<int, int,int> OnKill;

        /// <summary>
        /// 开启特效显示的最低品质要求
        /// </summary>
        private static readonly QualityEnum _OpenEffectQuality = QualityEnum.High;
        
        /// <summary>
        /// 完全开启枪械射击射线检测的最低品质要求
        /// </summary>
        private static readonly QualityEnum _OpenCompletePhysicsRaycastGunQuality = QualityEnum.High;
        /// <summary>
        /// 开启枪械射击射线检测范围 (低中低端机使用)
        /// </summary>
        public static float _OpenPhysicsRaycastGunDistance = 15;

        // 削韧值冷却时间
        private static readonly float _ToughnessColdDuration = 5f;
        // 飙血特效ID
        private static readonly int _OnHitEffectResID = 1010;
        // 恐吓冷却时间
        private static readonly float _ThreatenColdDuration = 2f;
        // 恐吓半径
        private static readonly float _ThreatenRadius = 18f;
        // 近战受击检测LayerMask
        public static readonly string BoxingOnHitLayerMaskName = "RaycastCollider";
        // 远程受击检测LayerMask
        public static readonly string[] HandGunOnHitLayerMaskNames = { "RaycastCollider", "RaycastColliderHead", "Default", "cityground" };   // 正向射线检测LayerMask
        public static readonly string[] HandGunReverseOnHitLayerMaskNames = { "RaycastCollider", "RaycastColliderHead" };   // 反向射线检测LayerMask
        public static readonly string HandGunOnHitHeadLayerName = "RaycastColliderHead";
        // 近战受击音效
        private static readonly string _BoxingOnHitSoundName = "sfx_battle_box_muffled";
        // 弹痕偏移值 (沿法线向上偏移一点距离，防止弹痕陷入墙里)
        private static readonly float _ObstacleOffset = 0.1f;
        // 普通飘字资源路径
        private static readonly int _ScoreHudResID = 1026;

        [SerializeField] 
        private Collider _onHitCollider;
        public Collider onHitCollider => _onHitCollider;

        [SerializeField]
        private Collider _headCollider;
        public Collider headCollider => _headCollider;
 
        // 是否开启伤害
        [SerializeField]
        private bool _OPEN_DAMAGE = true;

        private AIEntity _aiEntity;
        private AIData _aiData;
        
        // 当前锁定的敌人
        private AIEntity _currentLockTarget;
        private AIEntity _chaseRevengeTarget;

        public AIEntity ChaseRevengeTarget
        {
            set
            {
                _chaseRevengeTarget = value;
            }
            get
            {
                return _chaseRevengeTarget;
            }
        }

        // 仇恨的目标敌人 (最近一次攻击我的敌人)
        public AIEntity revengeTarget
        {
            get
            {
                if (Time.time <= _lostRevengeTimestamp || revengeColdDuration<0)
                {
                    return _revengeTarget;
                }
                return null;
            }
            set
            {
                _revengeTarget = value;
                _lostRevengeTimestamp = Time.time + _revengeColdDuration;
            }
        }
        private AIEntity _revengeTarget;
        // 失去仇恨的时间戳
        private float _lostRevengeTimestamp;
        // 仇恨冷却时间 (注意！！小于0则为永久仇恨)
        public float revengeColdDuration
        {
            get => _revengeColdDuration;
            set
            {
                _revengeColdDuration = value;
            }
        }
        private float _revengeColdDuration = 20f;
        // 是否刚刚被攻击
        public bool HasTakenDamage => _lastOnHitFrameCount == Time.frameCount - 1;
        // 上次受到攻击的帧数
        private int _lastOnHitFrameCount;
        // 附近的攻击目标
        private AIEntity _possibleTarget;
        public AIEntity possibleTarget
        {
            get { return _possibleTarget; }
            set { _possibleTarget = value; }
        }
        
        
        // 是否允许修改当前锁定的敌人
        public bool allowSwitchTarget = true;
        
        public AIEntity currentLockTarget
        {
            set
            {
                // 记录丢失目标时间戳
                if (_currentLockTarget!=value && value==null)
                {
                    lostLockTargetTimestamp = Time.time;
                    // if (_currentLockTarget.data.uniqueId == LibertyAIUtils.PLAYER_AI_ID)
                    // {
                    //     OnLockPlayer?.Invoke(_aiData.uniqueId, false);
                    // }
                }
                else
                {
                    // if (value && value.data.uniqueId == LibertyAIUtils.PLAYER_AI_ID)
                    // {
                    //     OnLockPlayer?.Invoke(_aiData.uniqueId, true);
                    // }
                }
                
                _currentLockTarget = value;
            }
            get => _currentLockTarget;
        }
        // 上次丢失锁定的敌人的时间戳
        private float _lostLockTargetTimestamp;

        public float lostLockTargetTimestamp
        {
            set
            {
                _lostLockTargetTimestamp = value;
            }
            get => _lostLockTargetTimestamp;
        }

        // 当前锁定目标距离
        private float _targetDistance = 0;
        public float targetDistance { set; get; }
        
        // 忽略的敌人列表
        private HashSet<AIEntity> _ignoreTargets = new HashSet<AIEntity>();
        public HashSet<AIEntity> ignoreTargets => _ignoreTargets;

        // 当前受击特效
        private Transform _currentOnHitEffect;
        
        // 当前受击飘字
        private Transform _currentOnHitFlyText;
        
        // 当前拾取道具特效ID
        private int _currentTakePropItemEffectID = 0;
        // 当前拾取道具特效
        private Transform _currentTakePropItemEffect;
        
        // 削韧重置时间戳
        private float _reduceToughnessResetTimestamp = -1;
        
        // 上次恐吓的时间戳
        private float _lastThreatenTimestamp;
        
        // 累计受到玩家伤害
        private int _totalDamageFromPlayer;
        // 重置累计受到玩家伤害的时间戳
        private float _resetTotalDamageFromPlayerTimestamp = -1;
        
        
        // // 弹夹内剩余弹药数量
        // private Dictionary<int, int> _restBulletCountDict = new Dictionary<int, int>();
        
        public void InitData(AIEntity aiEntity)
        {
            stopDeadEffect();
            
            _aiEntity = aiEntity;
            _aiData = aiEntity.data;
        }
        public void OnReset()
        {
            SetTarget(TargetType.ChaseRevengeTarget, null);
            SetTarget(TargetType.RevengeTarget, null);
            SetTarget(TargetType.PossibleTarget, null);
            SetTarget(TargetType.CurrentLockTarget, null);
        }
        void OnDestroy()
        {
            hideOnHitEffect(null);
            hideOnHitFlyText(null);
            hideTakePropItemEffect(null);
            stopDeadEffect();
            _aiEntity = null;
            _aiData = null;
        }

   

        void Update()
        {
            if (_aiData == null)
            {
                return;
            }
            UpdateReduceToughness();
            UpdateGrenade();
        }


        #region 韧性值

        /// <summary>
        /// 增加削韧值
        /// </summary>
        /// <param name="reduce"></param>
        /// <returns></returns>
        bool AddReduceToughness(int reduceThoughness)
        {
            _aiData.reduceToughness += reduceThoughness;
            
            // 是否触发受击动作
            if (_aiData.reduceToughness >= _aiData.maxToughness)
            {
                ResetReduceToughtness();
                return true;
            }
            
            _reduceToughnessResetTimestamp = Time.time;
            return false;
        }

        /// <summary>
        /// 刷新重置韧性值
        /// </summary>
        void UpdateReduceToughness()
        {
            if (_aiData.reduceToughness<=0 || _reduceToughnessResetTimestamp<=0)
            {
                return;
            }

            if (Time.time >= _reduceToughnessResetTimestamp)
            {
                ResetReduceToughtness();
            }
        }

        /// <summary>
        /// 重置韧性值
        /// </summary>
        void ResetReduceToughtness()
        {
            _aiData.reduceToughness = 0;
            _reduceToughnessResetTimestamp = -1;
        }

        #endregion

        #region 弹药数量
        
        /// <summary>
        /// 给武器重新装弹
        /// </summary>
        /// <param name="weaponId"></param>
        public void ReloadWeapon(int weaponId)
        {
            _aiEntity.WeaponSystem.ReloadWeapon(weaponId);
        }

        /// <summary>
        /// 使用武器，扣除弹夹内剩余子弹数量
        /// </summary>
        /// <param name="weaponId"></param>
        public void UseWeapon(int weaponId)
        {
            _aiEntity.WeaponSystem.UseWeapon(weaponId);
        }

        /// <summary>
        /// 获取弹夹内剩余子弹数量
        /// </summary>
        /// <param name="weaponId"></param>
        /// <returns></returns>
        public int GetRestBulletCount(int weaponId)
        {
            return _aiEntity.WeaponSystem.GetRestBulletCount(weaponId);
        }

        /// <summary>
        /// 获取当前武器弹夹内剩余子弹数量
        /// </summary>
        /// <returns></returns>
        public int GetRestBulletCount()
        {
            return GetRestBulletCount(_aiEntity.WeaponSystem.SelectedWeaponId);
        }
        
        /// <summary>
        /// 获取武器拥有子弹数量
        /// </summary>
        /// <param name="weaponId"></param>
        /// <returns></returns>
        public int GetMaxBulletCount(int weaponId)
        {
            return _aiEntity.WeaponSystem.GetMaxBulletCount(weaponId);
        }
        
        /// <summary>
        /// 获取当前武器拥有子弹数量
        /// </summary>
        /// <returns></returns>
        public int GetMaxBulletCount()
        {
            return GetMaxBulletCount(_aiEntity.WeaponSystem.SelectedWeaponId);
        }

        /// <summary>
        /// 获取武器弹夹容量
        /// </summary>
        /// <returns></returns>
        public int GetCapacityCount()
        {
            return _aiEntity.WeaponSystem.GetCapacity(_aiEntity.WeaponSystem.GetCapacity(_aiEntity.WeaponSystem.SelectedWeaponId));
        }

        /// <summary>
        /// 检测拥有子弹数量
        /// </summary>
        /// <returns></returns>
        public bool IsRestBulletCountEnough()
        {
            Weapon weapon = _aiEntity.WeaponSystem.HandleWeapon;
            if (weapon != null)
            {
                return weapon.MaxBullet == -1 || (weapon.MaxBullet-weapon.CurrentBullet) >0;
            }
            return false;
        }

        /// <summary>
        /// 检测武器子弹是否已满
        /// </summary>
        /// <returns></returns>
        public bool IsRestBulletCountFull()
        {
            Weapon weapon = _aiEntity.WeaponSystem.HandleWeapon;
            if (weapon != null)
            {
                return weapon.CurrentBullet >= weapon.Capacity;
            }
            return true;
        }

        #endregion

        // 检测是否是己方阵营
        public static bool CheckIsTeammateByTag(SideType selfSide, Collider other)
        {
            return CheckIsTeammateByTag(selfSide, other.gameObject);
        }
        public static bool CheckIsTeammateByTag(SideType selfSide, GameObject other)
        {
            if (other.CompareTag("Protected"))
            {
                return true;
            }
            
            switch (selfSide)
            {
                case SideType.Player:
                case SideType.Teammate:
                {
                    return other.CompareTag("Player") || other.CompareTag("Teammate");
                }
                case SideType.Npc:
                {
                    return other.CompareTag("Npc");
                }
            }

            return false;
        }
        
        // 检测是否是敌对阵营
        public static bool CheckIsEnemyByTag(SideType selfSide, Collider other)
        {
            return CheckIsEnemyByTag(selfSide, other.gameObject);
        }
        
        //检测是否是可破坏物体 或是 可交互物体
        public static bool CheckIsDestributeByTag(Collider other)
        {
            var tagIt = other.GetComponent<TagIt>();
            if (tagIt != null)
            {
                for (int i = 0; i < tagIt.tags.Count; i++)
                {
                    if (tagIt.tags[i] == Tag.CanDestroyed)
                    {
                        return true;
                    }
                }
            }

            var destructible = other.GetComponent<Destructible>();
            if (destructible != null)
            {
                return true;
            }
            
            var rigidbody = other.GetComponent<Rigidbody>();
            if (rigidbody != null)
            {
                return true;
            }

            return false;
        }
        public static bool CheckIsEnemyByTag(SideType selfSide, GameObject other)
        {
            if(other.CompareTag("Protected"))
            {
                return false;
            }
            
            switch (selfSide)
            {
                case SideType.Player:
                case SideType.Teammate:
                {
                    return other.CompareTag("Npc") || other.CompareTag("Hittable") || other.CompareTag("Madness");
                }
                case SideType.Npc:
                {
                    return other.CompareTag("Player") || other.CompareTag("Teammate");
                }
                case SideType.GameOpponent:
                {
                    return other.CompareTag("Hittable");
                }
                case SideType.Madness:
                case SideType.Grenade:
                case SideType.RPG:
                {
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// 尝试从collider上获取对应的AIEntity
        /// </summary>
        /// <param name="collider"></param>
        /// <param name="onlySearchNpc"></param>
        /// <returns></returns>
        public static AIEntity TryGetAIEntityFromCollider(Collider collider, bool onlySearchNpc = true)
        {
            AIEntity aiEntity = null;
            int uniqueId;
            if (int.TryParse(collider.name, out uniqueId))
            {
                aiEntity = LibertyAIUtils.GetNpc(uniqueId);
            }
            if(!aiEntity && !onlySearchNpc)
            {
                aiEntity = collider.GetComponent<AIEntity>();
            }
            return aiEntity;
        }
        
        /// <summary>
        /// 尝试从collider上获取对应的场景可破坏物体
        /// </summary>
        /// <param name="targetCollider"></param>
        /// <returns></returns>
        public static Destructible TryGetDestructibleyFromCollider(Collider targetCollider)
        {
            Destructible destructible = targetCollider.GetComponent<Destructible>();
            return destructible;
        }
        
        /// <summary>
        /// 尝试从collider上获取刚体
        /// </summary>
        /// <param name="targetCollider"></param>
        /// <returns></returns>
        public static Rigidbody TryGetRigidbodyFromCollider(Collider targetCollider)
        {
            if (!targetCollider.isTrigger)
            {
                Rigidbody rigidbody = targetCollider.GetComponent<Rigidbody>();
                return rigidbody;
            }

            return null;
        }

        /// <summary>
        /// 卸下当前武器
        /// </summary>
        public void UnLoadWeapon()
        {
            if (_aiEntity.WeaponSystem.HandleWeapon != null)
            {
                // 卸下当前装备的武器
                if (_aiEntity.weapon)
                {
                    PbEquipModelDataConfig equipModelDataConfig = LibertyConfigManager.GetInstance().GetEquipModelDataConfig(_aiEntity.WeaponSystem.HandleWeapon.Config.equip_id);
                    LibertyPoolMgr.GetInstance().RecycleEffect(equipModelDataConfig.resource_id, _aiEntity.weapon.transform);
                    _aiEntity.weapon = null;
                }
                // 清除IK
                _aiEntity.viewer.animationAgent.SetAimTransform((WeaponIKType)_aiEntity.WeaponSystem.HandleWeapon.Config.ik_type, null);
                // 清除弹夹
                HideMagazine();
            }
        }
        /// <summary>
        /// 切换武器 (返回是否切换了武器)
        /// </summary>
        /// <param name="weaponId"></param>
        public bool ChangeWeapon(int weaponId)
        {
            // 先卸下当前装备的武器
            if (_aiEntity.WeaponSystem.HandleWeapon != null)
            {
                // 是否已装备该武器
                if (_aiEntity.WeaponSystem.HandleWeapon.Config.weapon_id == weaponId)
                {
                    // 切换状态
                    {
                        BattleState battleState = BattleState.None;
                        PbWeaponDataConfig weaponDataConfig = LibertyConfigManager.GetInstance().GetWeaponDataConfig(weaponId);
                        if (weaponDataConfig != null)
                        {
                            battleState = (BattleState)weaponDataConfig.battle_state;
                        }
                        _aiEntity.viewer.animationAgent.EnterBattleState(battleState);
                    }
                    
                    return false;
                }
                
                // 卸下当前装备的武器、弹夹，并清除IK
                UnLoadWeapon();
            }

            if (weaponId > 0)
            {
                _aiEntity.WeaponSystem.ChangeWeapon(weaponId);

                // 穿戴武器
                PbWeaponDataConfig weaponDataConfig = LibertyConfigManager.GetInstance().GetWeaponDataConfig(weaponId);
                if (weaponDataConfig != null)
                {
                    if (weaponDataConfig.equip_id > 0)
                    {
                        PbEquipModelDataConfig equipModelDataConfig = LibertyConfigManager.GetInstance().GetEquipModelDataConfig(weaponDataConfig.equip_id);
                        // 绑定武器
                        Transform bindBone = GetBindBone((WeaponBindBoneType)equipModelDataConfig.bind_bone);

                        if (bindBone != null)
                        {
                            if (equipModelDataConfig.resource_id > 0)
                            {
                                Transform weaponTransform = LibertyPoolMgr.GetInstance().GetEffectObject(equipModelDataConfig.resource_id);
                                weaponTransform.gameObject.SetActive(true);
                                weaponTransform.SetParent(bindBone);
                                weaponTransform.localPosition = new Vector3(equipModelDataConfig.position[0], equipModelDataConfig.position[1], equipModelDataConfig.position[2]);
                                weaponTransform.localEulerAngles = new Vector3(equipModelDataConfig.rotation[0], equipModelDataConfig.rotation[1], equipModelDataConfig.rotation[2]);
                                //weaponTransform.localScale = new Vector3(equipModelDataConfig.scale, equipModelDataConfig.scale, equipModelDataConfig.scale);
                                Vector3 lossyScale = bindBone.lossyScale;
                                weaponTransform.localScale = new Vector3(equipModelDataConfig.scale/lossyScale.x, equipModelDataConfig.scale/lossyScale.y, equipModelDataConfig.scale/lossyScale.z);
                                _aiEntity.weapon = weaponTransform.GetComponent<LibertyWeapon>();
                                _aiEntity.weapon.ChangeLod(0);
                            
                                // 设置IK
                                _aiEntity.viewer.animationAgent.SetAimTransform((WeaponIKType)weaponDataConfig.ik_type, weaponTransform);

                            }
                        }
                        else if((WeaponBindBoneType)equipModelDataConfig.bind_bone != WeaponBindBoneType.None)
                        {
                            Debug.LogError(LogModule.LibertySceneBattle,$"模型 {_aiEntity.viewer.animator.name} 未找到骨骼节点: {equipModelDataConfig.bind_bone.ToString()}");
                        }
                    }
                    
                    BattleState battleState = (BattleState)weaponDataConfig.battle_state;
                    _aiEntity.viewer.animationAgent.EnterBattleState(battleState);
                    _aiEntity.viewer.animationAgent.EnterAimingState(AimingState.None);
                }
            }
            else
            {
                _aiEntity.viewer.animationAgent.EnterBattleState(BattleState.None);
                _aiEntity.viewer.animationAgent.EnterAimingState(AimingState.None);
                
                _aiEntity.WeaponSystem.SwitchEmpty();
            }
            return true;
        }

        /// <summary>
        /// 显示弹夹
        /// </summary>
        /// <param name="magazine_id"></param>
        public void ShowMagazine()
        {
            int magazine_id = 0;
            PbWeaponDataConfig weaponDataConfig = _aiEntity.WeaponSystem.HandleWeapon.Config;
            if (weaponDataConfig!=null)
            {
                magazine_id = weaponDataConfig.magazine_id;
            }
            
            if (magazine_id <= 0)
            {
                return;
            }
            
            // 隐藏子弹弹夹挂点
            if (_aiEntity.weapon)
            {
                _aiEntity.weapon.ClipPoint?.SetActive(false);
            }
            
            PbEquipModelDataConfig equipModelDataConfig = LibertyConfigManager.GetInstance().GetEquipModelDataConfig(magazine_id);
            if (equipModelDataConfig != null)
            {
                // 绑定弹夹
                Transform bindBone = GetBindBone((WeaponBindBoneType)equipModelDataConfig.bind_bone);
                if (bindBone != null)
                {
                    if (equipModelDataConfig.resource_id > 0)
                    {
                        Transform magazineTransform = LibertyPoolMgr.GetInstance().GetEffectObject(equipModelDataConfig.resource_id);
                        magazineTransform.gameObject.SetActive(true);
                        magazineTransform.SetParent(bindBone);
                        magazineTransform.localPosition = new Vector3(equipModelDataConfig.position[0], equipModelDataConfig.position[1], equipModelDataConfig.position[2]);
                        magazineTransform.localEulerAngles = new Vector3(equipModelDataConfig.rotation[0], equipModelDataConfig.rotation[1], equipModelDataConfig.rotation[2]);
                        magazineTransform.localScale = new Vector3(equipModelDataConfig.scale, equipModelDataConfig.scale, equipModelDataConfig.scale);
                
                        _aiEntity.magazine = magazineTransform;
                    }
                }
                else if((WeaponBindBoneType)equipModelDataConfig.bind_bone != WeaponBindBoneType.None)
                {
                    Debug.LogError(LogModule.LibertySceneBattle,$"模型 {_aiEntity.viewer.animator.name} 未找到骨骼节点: {equipModelDataConfig.bind_bone.ToString()}");
                }
            }
        }

        /// <summary>
        /// 隐藏弹夹
        /// </summary>
        public void HideMagazine()
        {
            // 隐藏子弹弹夹挂点
            if (_aiEntity.weapon)
            {
                _aiEntity.weapon.ClipPoint?.SetActive(true);
            }
            
            if (_aiEntity.magazine)
            {
                PbEquipModelDataConfig equipModelDataConfig = LibertyConfigManager.GetInstance().GetEquipModelDataConfig(_aiEntity.WeaponSystem.HandleWeapon.Config.magazine_id);
                LibertyPoolMgr.GetInstance().RecycleEffect(equipModelDataConfig.resource_id, _aiEntity.magazine);
                _aiEntity.magazine = null;
            }
        }

        /// <summary>
        /// 获取绑定的骨骼节点
        /// </summary>
        /// <param name="bind_bone"></param>
        /// <returns></returns>
        Transform GetBindBone(WeaponBindBoneType bind_bone)
        {
            Transform bindBone = null;
            switch (bind_bone)
            {
                case WeaponBindBoneType.RightHand:
                    {
                        bindBone = _aiEntity.viewer.animator.GetBoneTransform(HumanBodyBones.RightHand);
                    }
                    break;
                    
                case WeaponBindBoneType.LeftHand:
                    {
                        bindBone = _aiEntity.viewer.animator.GetBoneTransform(HumanBodyBones.LeftHand);
                    }
                    break;
            }
            return bindBone;
        }

        /// <summary>
        /// 玩家锁定敌人
        /// </summary>
        public void PlayerSearchLockTarget()
        {
            // 非战斗状态
            if (_aiData.battleState==BattleState.None || _aiData.aimingState==AimingState.None)
            {
                currentLockTarget = null;
                return;
            }
            
            Transform attacker = _aiEntity.viewer.animator.transform;
            PbAIPropertyDataConfig aiPropertyDataConfig = _aiEntity.propertyDataConfig;
            Vector3 position = attacker.position;
            Vector3 bodyPosition = position + Vector3.up;
            
            // 是否可以锁定身后的敌人
            bool canLockEnemyBack = true;
            // 视野范围
            float vision = aiPropertyDataConfig.vision;
            if (_aiData.battleState==BattleState.HandGun || _aiData.battleState==BattleState.AutoRifle)
            {
                // 武器用射程代替视野范围
                PbWeaponDataConfig weaponDataConfig = _aiEntity.WeaponSystem.HandleWeapon.Config;
                if (weaponDataConfig != null)
                {
                    vision = weaponDataConfig.range;
                }

                // 不允许锁定身后的敌人
                canLockEnemyBack = false;

                // // TODO: test
                // currentLockTarget = null;  // TODO: test
                // return; // TODO: test
            }
            
            // 物理检测
            int count;
            Collider[] results = PhysicsUtils.OverlapSphereNonAlloc(out count, attacker.position, vision, BoxingOnHitLayerMaskName);

            AIEntity lockTarget = null;
            float minMagnitude = float.MaxValue;
            float magnitude;
            AIEntity target = null;
            Renderer renderer = null;
            Vector3 targetBodyPosition, direction;
            RaycastHit raycastHit;
            for (int i = 0; i < count; ++i)
            {
                Collider collider = results[i];
                // 检测是否是敌人
                if (CheckIsEnemyByTag(_aiData.side, collider))
                {
                    target = TryGetAIEntityFromCollider(collider);
                    if (!target)
                    {
                        continue;
                    }
                    // 检测距离
                    magnitude = target.data.distanceToPlayer;
                    if (magnitude >= minMagnitude)
                    {
                        continue;
                    }
                    // 检测物体是否可见
                    if (target.data.isAlive)
                    {
                        renderer = target.viewer.animator.GetComponentInChildren<SkinnedMeshRenderer>();
                        if (renderer && renderer.isVisible)
                        {
                            // 处理在身后的敌人
                            if (!canLockEnemyBack)
                            {
                                if (Vector3.Dot(attacker.forward, (renderer.transform.position - attacker.position).normalized) < 0)
                                {
                                    continue;
                                }
                            }
                            
// #if UNITY_EDITOR
                            // 编辑器模式下，如果Renderer对Scene的相机可见，isVisible也为true，所以多加一层判断
                            {
                                Camera camera = LibertyAIUtils.PlayerController.cameraController.playerCamera;
                                Vector3 viewPos = camera.WorldToViewportPoint(renderer.transform.position);
                                if (viewPos.z<0 || viewPos.z>camera.farClipPlane || viewPos.x<0 || viewPos.x>1 || viewPos.y<0 || viewPos.y>1)
                                {
                                    continue;
                                }
                            }
// #endif
                            
                            // 射线检测是否被阻挡
                            targetBodyPosition = collider.transform.position + Vector3.up;
                            direction = targetBodyPosition - bodyPosition;
                            bool hit = PhysicsUtils.RaycastNonAlloc(out raycastHit, bodyPosition, direction.normalized, magnitude, HandGunOnHitLayerMaskNames);
                            if (!hit || raycastHit.collider!=collider)
                            {
                                continue;
                            }
                            
                            minMagnitude = magnitude;
                            lockTarget = target;
                        }
                    }
                }
            }

            currentLockTarget = lockTarget;
        }

        /// <summary>
        /// NPC锁定敌人
        /// </summary>
        public void NpcSearchLockTarget(bool autoLockPlayer, TargetType storeTargetType)
        {
            Transform attacker = _aiEntity.viewer.animator.transform;
            PbAIPropertyDataConfig aiPropertyDataConfig = _aiEntity.propertyDataConfig;
            Vector3 position = attacker.position;
            // Vector3 bodyPosition = position + Vector3.up;
   
            // 视野范围
            float vision = aiPropertyDataConfig.vision;

            AIEntity lockTarget = null;
            do
            {
                AIEntity target = null;

                // 当前默认直接锁定玩家
                if (autoLockPlayer)
                {
                    target = LibertyAIUtils.GetPlayerEntity();
                    if (target && target.data.isAlive)
                    {
                        // 是否在视野范围内
                        if (Vector3.Distance(target.viewer.animator.transform.position, position) <= vision)
                        {
                            Collider collider = target.onHitCollider;
                            if (CheckIsEnemyByTag(_aiData.side, collider))
                            {
                                lockTarget = target;
                                break;
                            }
                        }
                    }
                }
                else
                {
                    // 物理检测
                    int count;
                    Collider[] results = PhysicsUtils.OverlapSphereNonAlloc(out count, attacker.position, vision, BoxingOnHitLayerMaskName);

                    float minMagnitude = float.MaxValue;
                    float magnitude;
                    Renderer renderer = null;
                    Vector3 targetBodyPosition, direction;
                    RaycastHit raycastHit;
                    for (int i = 0; i < count; ++i)
                    {
                        Collider collider = results[i];
                        GameObject colliderGameObject = collider.gameObject;
                        // 检测是否属于忽略物体
                        if (collider==_aiEntity.onHitCollider || collider==_aiEntity.headCollider || colliderGameObject==_aiEntity.characterController.gameObject)
                        {
                            continue;
                        }
                        // 检测是否是敌人
                        if (CheckIsEnemyByTag(_aiData.side, collider))
                        {
                            target = TryGetAIEntityFromCollider(collider);
                            if (!target)
                            {
                                continue;
                            }
                            // 是否忽略
                            if (ignoreTargets.Contains(target))
                            {
                                continue;
                            }
                            // 检测距离
                            magnitude = Vector3.Distance(position, target.battleAgent.transform.position);
                            if (magnitude >= minMagnitude)
                            {
                                continue;
                            }
                            // 检测物体是否可见
                            if (target.data.isAlive)
                            {
                                renderer = target.viewer.animator.GetComponentInChildren<SkinnedMeshRenderer>();
                                if (renderer && renderer.isVisible)
                                {
                                    // // 处理在身后的敌人
                                    // if (Vector3.Dot(attacker.forward, (renderer.transform.position - attacker.position).normalized) < 0)
                                    // {
                                    //     continue;
                                    // }
                                    
                                    // // 编辑器模式下，如果Renderer对Scene的相机可见，isVisible也为true，所以多加一层判断
                                    // {
                                    //     Camera camera = LibertyAIUtils.PlayerController.cameraController.playerCamera;
                                    //     Vector3 viewPos = camera.WorldToViewportPoint(renderer.transform.position);
                                    //     if (viewPos.z<0 || viewPos.z>camera.farClipPlane || viewPos.x<0 || viewPos.x>1 || viewPos.y<0 || viewPos.y>1)
                                    //     {
                                    //         continue;
                                    //     }
                                    // }
                                    
                                    // // 射线检测是否被阻挡
                                    // targetBodyPosition = collider.transform.position + Vector3.up;
                                    // direction = targetBodyPosition - bodyPosition;
                                    // bool hit = PhysicsUtils.RaycastNonAlloc(out raycastHit, bodyPosition, direction.normalized, magnitude, HandGunOnHitLayerMaskNames);
                                    // if (!hit || raycastHit.collider!=collider)
                                    // {
                                    //     continue;
                                    // }
                                    
                                    minMagnitude = magnitude;
                                    lockTarget = target;
                                }
                            }
                        }
                    }
                }
                

            } while (false);
            
            SetTarget(storeTargetType, lockTarget);
        }

        /// <summary>
        /// 转向当前锁定目标
        /// </summary>
        public void FaceToCurrentLockTarget()
        {
            Transform attacker = _aiEntity.viewer.animator.transform;
            
            // 朝向目标
            if (currentLockTarget != null)
            {
                Transform defender = currentLockTarget.viewer.animator.transform;
                Vector3 direction = defender.position - attacker.position;
                direction.y = 0;
                Quaternion rotation = Quaternion.LookRotation(direction);
                if (_aiData.uniqueId == LibertyAIUtils.PLAYER_AI_ID)
                {
                    // 玩家
                    // Debug.LogError(LogModule.LibertySceneBattle, $"=====朝向目标===={rotation.eulerAngles}=====");
                    // LibertyAIUtils.PlayerController.PlayerTransmission(attacker.position, rotation.eulerAngles, false);

                    var playerModel = LibertyAIUtils.PlayerController.playerModel;
                    var inputController = LibertyAIUtils.PlayerController.inputController;
                    _aiEntity.SetRotation(rotation.eulerAngles);
                    inputController.LastDirection = playerModel.transform.forward;
                }
                else
                {
                    // AI
                    _aiEntity.seeker.LocomotionAgent.SetForceUpdateTargetRotation(rotation);
                }
            }
        }

        public AnimationAgent.BoxingMoveType CheckBoxingMoveTypeToCurrentLockTarget()
        {
            AnimationAgent.BoxingMoveType boxingMoveType = AnimationAgent.BoxingMoveType.None;
            if (currentLockTarget != null)
            {
                // 计算位移
                if (_aiData.uniqueId == LibertyAIUtils.PLAYER_AI_ID)
                {
                    // 玩家
                    if (currentLockTarget.data.distanceToPlayer >= AnimationAgent.BoxingMoveVeryLongThreshold)
                    {
                        // 长位移
                        boxingMoveType = AnimationAgent.BoxingMoveType.VeryLong;
                    }
                    else if (currentLockTarget.data.distanceToPlayer >= AnimationAgent.BoxingMoveLongThreshold)
                    {
                        // 中位移
                        boxingMoveType = AnimationAgent.BoxingMoveType.Long;
                    }
                    else if (currentLockTarget.data.distanceToPlayer >= AnimationAgent.BoxingMoveShortThreshold)
                    {
                        // 短位移
                        boxingMoveType = AnimationAgent.BoxingMoveType.Short;
                    }
                }
                else
                {
                    // npc
                    
                }
            }

            return boxingMoveType;
        }

        /// <summary>
        /// 是否可以对当前锁定目标进行倒地攻击
        /// </summary>
        /// <returns></returns>
        public bool CanAttackDownCurrentLockTarget()
        {
            if (currentLockTarget != null)
            {
                // 目标在倒地状态下
                if (currentLockTarget.data.animationState == AnimationState.OnHitDown ||
                    currentLockTarget.data.animationState == AnimationState.OnHitGetUp)
                {
                    PbBoxingDataConfig boxingDataConfig = LibertyConfigManager.GetInstance().GetBoxingDataConfig(_aiData.uniqueId, AnimationState.BoxingAttackDown);
                    float radius = boxingDataConfig.range_parameter_1;  // 扇形半径
                    if (Vector3.Distance(currentLockTarget.viewer.animator.transform.position,
                            _aiEntity.viewer.animator.transform.position) <= radius)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        /// <summary>
        /// 是否可以对当前锁定目标进行手枪近战攻击
        /// </summary>
        /// <returns></returns>
        public bool CanHandGunBoxingCurrentLockTarget()
        {
            if (currentLockTarget != null)
            {
                PbBoxingDataConfig boxingDataConfig = LibertyConfigManager.GetInstance().GetBoxingDataConfig(_aiData.uniqueId, AnimationState.HandGunBoxing);
                float radius = boxingDataConfig.range_parameter_1;  // 扇形半径
                if (Vector3.Distance(currentLockTarget.viewer.animator.transform.position,
                        _aiEntity.viewer.animator.transform.position) <= radius)
                {
                    return true;
                }
            }
            
            return false;
        }

        /// <summary>
        /// 恐吓附近的npc逃跑、战斗
        /// </summary>
        /// <param name="ignoreNpcs">忽略列表</param>
        public void ThreatenNearNpc(HashSet<AIEntity> ignoreNpcs)
        {
            // 冷却时间
            if (Time.time < _lastThreatenTimestamp + _ThreatenColdDuration)
            {
                return;
            }
            
            Transform attacker = _aiEntity.viewer.animator.transform;

            int count;
            Collider[] results = PhysicsUtils.OverlapSphereNonAlloc(out count, attacker.position, _ThreatenRadius, BoxingOnHitLayerMaskName);
            for (int i = 0; i < count; ++i)
            {
                Collider collider = results[i];
                // 检测是否是敌人
                if (CheckIsEnemyByTag(_aiData.side, collider))
                {
                    AIEntity aiEntity = TryGetAIEntityFromCollider(collider);
                    if (aiEntity)
                    {
                        // npc当前状态是否可逃跑
                        if (!aiEntity.data.canBeThreaten)
                        {
                            continue;
                        }
                        // 是否忽略
                        if (ignoreNpcs.Contains(aiEntity))
                        {
                            continue;
                        }
                        
                        // 根据AI行为模型，切换行为状态
                        switch (aiEntity.data.npcAIModel)
                        {
                            case NpcAIModel.None:
                            case NpcAIModel.Escape:
                                {
                                    aiEntity.data.npcStatus = NpcStatus.Escape;
                                }
                                break;

                            default:
                                {
                                    aiEntity.data.npcStatus = NpcStatus.Battle;
                                }
                                break;
                        }
                    }
                }
            }
            
            _lastThreatenTimestamp = Time.time;
        }

        /// <summary>
        /// 近战攻击
        /// </summary>
        /// <param name="character"></param>
        public void BoxingAttack(AnimationState animationState)
        {
            Transform attacker = _aiEntity.viewer.animator.transform;
            
            // 伤害范围
            PbBoxingDataConfig boxingDataConfig = LibertyConfigManager.GetInstance().GetBoxingDataConfig(_aiData.uniqueId, animationState);
            float radius = boxingDataConfig.range_parameter_1;  // 扇形半径
            float degree = boxingDataConfig.range_parameter_2;  // 扇形角度
            // 伤害计算
            PbAIPropertyDataConfig aiPropertyDataConfig = _aiEntity.propertyDataConfig;
            int damageHP = Mathf.FloorToInt(aiPropertyDataConfig.basic_atk * boxingDataConfig.atk_bonus / 10000f);
#if UNITY_EDITOR
            if (!_OPEN_DAMAGE)
            {
                damageHP = 0;
            }
#endif

            // 击中敌人列表
            HashSet<AIEntity> hitEnemies = HashSetPool<AIEntity>.Get();
            hitEnemies.Clear();
            // 是否有击中目标
            bool hasHitted = false;
            // 物理检测
            int count;
            Collider[] results = PhysicsUtils.OverlapFanNonAlloc(out count, attacker.position, radius, attacker.forward, degree, BoxingOnHitLayerMaskName);
            for (int i = 0; i < count; ++i)
            {
                Collider collider = results[i];
                GameObject colliderGameObject = collider.gameObject;
                // 检测是否属于忽略物体
                if (collider==_aiEntity.onHitCollider || collider==_aiEntity.headCollider || colliderGameObject==_aiEntity.characterController.gameObject)
                {
                    continue;
                }
                // 检测是否是敌人
                if (CheckIsEnemyByTag(_aiData.side, collider))
                {
                    AIEntity aiEntity = TryGetAIEntityFromCollider(collider);
                    if (aiEntity)
                    {
                        // 击中角色
                        aiEntity.battleAgent.OnHit(_aiEntity, damageHP, animationState, false,101);
                        hitEnemies.Add(aiEntity);
                        hasHitted = true;
                    }
                    else
                    {
                        // 击中物体
                        var hittable = collider.GetComponent<IHittable>();
                        if (hittable != null)
                        {
                            hittable.OnHit(_aiEntity, damageHP, animationState, false,101);
                            hasHitted = true;
                        }
                    }
                }
            }
            
            // 更新最后战斗状态的时间戳
            _aiEntity.viewer.animationAgent.UpdateLastBattleTimestamp();

            // 玩家击中npc，让其逃跑
            if (hasHitted && _aiData.uniqueId == LibertyAIUtils.PLAYER_AI_ID)
            {
                ThreatenNearNpc(hitEnemies);
            }
            
            // 回收
            HashSetPool<AIEntity>.Release(hitEnemies);
        }

        /// <summary>
        /// 用物理射线检测的枪械攻击
        /// </summary>
        public void PhysicsRaycastGunAttack(AnimationState animationState)
        {
            PbWeaponDataConfig weaponDataConfig = _aiEntity.WeaponSystem.HandleWeapon.Config;
            if (weaponDataConfig == null)
            {
                return;
            }
            PbWeaponBulletDataConfig weaponBulletDataConfig = LibertyConfigManager.GetInstance().GetWeaponBulletDataConfig(weaponDataConfig.bullet_id);
            if (GetRestBulletCount() <= 0 && GetCapacityCount() > 0)
            {
                return;
            }
            
            // 扣除子弹
            UseWeapon(weaponDataConfig.weapon_id);
            
            // 是否使用射线检测
            bool isUseRaycast = _aiData.uniqueId == LibertyAIUtils.PLAYER_AI_ID 
                                || (int)QualityManager.Inst.CurrentQuality >= (int)_OpenCompletePhysicsRaycastGunQuality; 
                                // || _aiData.distanceToPlayer <= _OpenPhysicsRaycastGunDistance;
            
            Transform attacker = _aiEntity.viewer.animator.transform;
            // 武器
            LibertyWeapon weapon = _aiEntity.weapon;
            // 武器开火位置
            Vector3 weaponPosition = _aiData.rangedWeaponFirePosition;
            // 准星位置
            Vector3 aimPosition = _aiData.aimPosition;
            // 射线起点
            Vector3 raycastOrigin = weaponPosition;
            // 如果是玩家，并且是自由射击的情况下，射线从camera处发射
            if (_aiData.uniqueId == LibertyAIUtils.PLAYER_AI_ID && LibertyAIUtils.PlayerController.playerLockTargetHelper.UseFreeAim)
            {
                raycastOrigin = LibertyAIUtils.PlayerController.cameraController.playerCamera.transform.position;
                // 向前移动相机跟角色的偏移值，防止自由瞄准时，射线击中人物后背
                Vector3 direction = (aimPosition - raycastOrigin).normalized;
                raycastOrigin += direction * Vector3.Dot(direction, (weaponPosition - raycastOrigin));
            }

            // 击中敌人列表
            HashSet<AIEntity> hitEnemies = HashSetPool<AIEntity>.Get();
            hitEnemies.Clear();
            // 是否命中敌人
            bool hitTarget = false;
            // 命中敌人的Collider
            Collider targetCollider = null;
            // 是否击杀敌人
            bool killTarget = false;
            // 弹道拖尾结束点
            Vector3 trailEnd = aimPosition;
            

            // 1.先做射线检测，物理检测可能会命中物体，打到物体的话，需要记录位置显示弹痕
            // 射线检测命中的数据
            bool isRaycastHit = false;
            Vector3 raycastHitPoint = Vector3.zero;
            Vector3 raycastHitNormal = Vector3.zero;
            // 物理检测
            if (isUseRaycast)
            {
                RaycastHit[] raycastHits;
                int count = PhysicsUtils.RaycastNonAlloc(out raycastHits, raycastOrigin, (aimPosition-raycastOrigin).normalized, weaponDataConfig.range, HandGunOnHitLayerMaskNames);
                if(count > 0)
                {
                    // 找到距离最近不忽略的物体
                    int minIndex = -1;
                    float minDistance = float.MaxValue;
                    float distance;
                    for (int i = 0; i < count; ++i)
                    {
                        Collider collider = raycastHits[i].collider;
                        GameObject colliderGameObject = collider.gameObject;
                        distance = raycastHits[i].distance;
                        
                        // 检测是否属于忽略物体
                        if (collider==_aiEntity.onHitCollider || collider==_aiEntity.headCollider || colliderGameObject==_aiEntity.characterController.gameObject)
                        {
                            continue;
                        }
                        
                        // 检测是否是己方势力
                        if (CheckIsTeammateByTag(_aiData.side, collider))
                        {
                            continue;
                        }
                    
                        if (distance < minDistance)
                        {
                            minIndex = i;
                            minDistance = distance;
                        }
                    }

                    if (minIndex >= 0)
                    {
                        RaycastHit raycastHit = raycastHits[minIndex];
                        Collider collider = raycastHit.collider;
                        Debug.Log(LogModule.LibertySceneBattle, $"{_aiEntity.id} 射击击中物体 {collider.name}, 击中位置 ({raycastHit.point.x}, {raycastHit.point.y}, {raycastHit.point.z}), 击中点法线 ({raycastHit.normal.x}, {raycastHit.normal.y}, {raycastHit.normal.z}) ");
                        isRaycastHit = true;
                        raycastHitPoint = raycastHit.point;
                        raycastHitNormal = raycastHit.normal;
                        
                        // 检测是否是敌人
                        if (CheckIsEnemyByTag(_aiData.side, collider))
                        {
                            targetCollider = collider;
                        }

                        if (CheckIsDestributeByTag(collider))
                        {
                            targetCollider = collider;
                        }
                        
                        trailEnd = raycastHit.point;
                    }

                }

                // 2.如果射线检测没有命中敌人，再反向做射线检测，处理射线起点在敌人包围盒中的情况
                if (!targetCollider)
                {
                    Vector3 reverseRaycastOrigin = raycastOrigin + (aimPosition - raycastOrigin).normalized * weaponDataConfig.range;
                    count = PhysicsUtils.RaycastNonAlloc(out raycastHits, reverseRaycastOrigin, -(aimPosition-raycastOrigin).normalized, weaponDataConfig.range, HandGunReverseOnHitLayerMaskNames);
                    if(count > 0)
                    {
                        // 找到距离最近不忽略的物体
                        int maxIndex = -1;
                        float maxDistance = float.MinValue;
                        float distance;
                        for (int i = 0; i < count; ++i)
                        {
                            Collider collider = raycastHits[i].collider;
                            GameObject colliderGameObject = collider.gameObject;
                            distance = raycastHits[i].distance;
                            
                            // 检测是否属于忽略物体
                            if (collider==_aiEntity.onHitCollider || collider==_aiEntity.headCollider || colliderGameObject==_aiEntity.characterController.gameObject)
                            {
                                continue;
                            }
                            
                            // 检测是否是己方势力
                            if (CheckIsTeammateByTag(_aiData.side, collider))
                            {
                                continue;
                            }

                            if (distance > maxDistance)
                            {
                                maxIndex = i;
                                maxDistance = distance;
                            }
                        }

                        if (maxIndex >= 0)
                        {
                            RaycastHit raycastHit = raycastHits[maxIndex];
                            Collider collider = raycastHit.collider;
                        
                            Debug.Log(LogModule.LibertySceneBattle, $"射击反向射线击中物体 {collider.name}, 击中位置 ({raycastHit.point.x}, {raycastHit.point.y}, {raycastHit.point.z}), 击中点法线 ({raycastHit.normal.x}, {raycastHit.normal.y}, {raycastHit.normal.z}) ");

                            // 检测是否是敌人
                            if (CheckIsEnemyByTag(_aiData.side, collider))
                            {
                                targetCollider = collider;
                            }
                        }

                    }
                }
            }
            else
            {
                if (currentLockTarget != null)
                {
                    targetCollider = currentLockTarget.onHitCollider;
                    trailEnd = targetCollider.transform.TransformPoint(targetCollider.bounds.center);
                }
            }


            if (targetCollider)
            {
                foreach (var elementId in weaponBulletDataConfig.elements)
                {
                    PbWeaponElementDataConfig weaponElementDataConfig = LibertyConfigManager.GetInstance().GetWeaponElementDataConfig(elementId);
                    if (weaponElementDataConfig != null)
                    {
                        switch ((WeaponElementType)weaponElementDataConfig.element_type)
                        {
                            case WeaponElementType.Damage:
                                {
                                    // 计算伤害
                                    int damageHP = Mathf.FloorToInt(_aiEntity.propertyDataConfig.basic_atk * weaponElementDataConfig.value / 10000f);
#if UNITY_EDITOR
                                    if (!_OPEN_DAMAGE)
                                    {
                                        damageHP = 0;
                                    }
#endif
                                    // 命中敌人
                                    AIEntity aiEntity = TryGetAIEntityFromCollider(targetCollider);
                                    if (aiEntity)
                                    {
                                        aiEntity.battleAgent.OnHit(_aiEntity, damageHP, animationState, targetCollider.gameObject.layer==LayerMask.NameToLayer(HandGunOnHitHeadLayerName),weaponDataConfig.weapon_id);
                                        hitEnemies.Add(aiEntity);
                                        hitTarget = true;
                                        killTarget = !aiEntity.data.isAlive;
                                    }
                                    else
                                    {
                                        // 击中物体
                                        var hittable = targetCollider.GetComponent<IHittable>();
                                        if (hittable != null)
                                        {
                                            hittable.OnHit(_aiEntity, damageHP, animationState, targetCollider.gameObject.layer==LayerMask.NameToLayer(HandGunOnHitHeadLayerName),weaponDataConfig.weapon_id);
                                            hittable.OnGunHitPoint(raycastHitPoint, raycastHitNormal);
                                            hitTarget = true;
                                        }
                                    }
                
                                    //命中场景物体
                                    Destructible destructible = TryGetDestructibleyFromCollider(targetCollider);
                                    if (destructible!=null)
                                    {
                                        var interact_type = weaponElementDataConfig.interact_type;
                                        if (interact_type != 0)
                                        {
                                            var times = 1;
                                            var interacterCfg = LibertyConfigManager.GetInstance().GetWeaponInteractDataConfig(interact_type,(int)destructible.DestructibleType);
                                            if (interacterCfg!=null)
                                            {
                                                times = interacterCfg.dmg_coef / 10000;
                                            }
                                            destructible.ApplyDamage(damageHP * times);
                                        }
                                        hitTarget = true;
                                        // 弹孔特效
                                        showWeaponObstacleEffect(raycastHitPoint, raycastHitNormal);
                                    }
                                }
                                break;

                            case WeaponElementType.Force:
                                {
                                    Rigidbody rigidbody = TryGetRigidbodyFromCollider(targetCollider);
                                    if (rigidbody!=null)
                                    {
                                        var direction = (raycastHitPoint - raycastOrigin).normalized;
                                        var force = weaponElementDataConfig.parameter_03;
                                        rigidbody.AddForce(direction * force);
                                    }
                                }
                                break;
                        }
                        
                    }
                }
               
                
            }
            else if(isRaycastHit)
            {
                // 弹孔特效
                showWeaponObstacleEffect(raycastHitPoint, raycastHitNormal);
            }

            
            // 武器开火特效
            showWeaponFireEffect();
            // 弹道特效
            showWeaponTrailEffect(weaponPosition, trailEnd);
            
            if (_aiData.uniqueId == LibertyAIUtils.PLAYER_AI_ID)
            {
                // 如果是玩家，播放锁定目标特效的动画
                LibertyAIUtils.PlayerController.playerLockTargetHelper.PlayLockTargetEffectAttackAnimation(hitTarget, killTarget);
                
                // 玩家开枪，让附近npc逃跑
                ThreatenNearNpc(hitEnemies);
                
                // 处理后坐力
                var recoil_limit = weaponDataConfig.recoil_limit;
                LibertyAIUtils.PlayerController.inputCamera.RecoilAnglesLimit = new Vector4(recoil_limit[0], recoil_limit[1], recoil_limit[2], recoil_limit[3]);
                var recoil_offset = weaponDataConfig.recoil_offset;
                if (recoil_offset!=null && recoil_offset.Count > 0)
                {
                    LibertyAIUtils.PlayerController.inputCamera.AddRecoil(Random.Range(recoil_offset[0], recoil_offset[1]), Random.Range(recoil_offset[2], recoil_offset[3]));
                }
            }

            // 更新最后战斗状态的时间戳
            _aiEntity.viewer.animationAgent.UpdateLastBattleTimestamp();
            
            // 回收
            HashSetPool<AIEntity>.Release(hitEnemies);
        }

        /// <summary>
        /// 扔出手雷
        /// </summary>
        /// <param name="endPoint"></param>
        /// <param name="maxHeight"></param>
        public void ThrowGrenade(Vector3 endPoint, float maxHeight)
        {
            // 扣除子弹
            _aiEntity.battleAgent.UseWeapon(_aiEntity.WeaponSystem.EquippedGrenade.Id);
            
            LibertyWeapon libertyWeapon = _aiEntity.weapon;
            PbWeaponDataConfig weaponDataConfig = _aiEntity.WeaponSystem.EquippedGrenade.Config;
            if (weaponDataConfig != null && libertyWeapon != null)
            {
                PbWeaponBulletDataConfig weaponBulletDataConfig = LibertyConfigManager.GetInstance().GetWeaponBulletDataConfig(weaponDataConfig.bullet_id);
                if (weaponBulletDataConfig != null)
                {
                    // 扔出手雷
                    Transform grenadeTransform = LibertyPoolMgr.GetInstance().GetEffectObject(weaponBulletDataConfig.model);
                    grenadeTransform.SetActive(true);
                    grenadeTransform.SetPositionAndRotation(libertyWeapon.transform.position, libertyWeapon.transform.rotation);
                    BaseThrowable baseThrowable = grenadeTransform.GetComponent<BaseThrowable>();
                    baseThrowable.InitBullet(weaponDataConfig, weaponBulletDataConfig, _aiEntity);
                    Rigidbody grenadeRigidbody = grenadeTransform.GetComponent<Rigidbody>();
                    grenadeRigidbody.Sleep();
                    Parabola.AddRigidbodyForce(grenadeRigidbody, libertyWeapon.transform.position, endPoint, maxHeight);
                }
            }
        }

        /// <summary>
        /// 射出火箭弹
        /// </summary>
        public void FireRPG(Vector3 position, Vector3 direction)
        {
            // 扣除子弹
            _aiEntity.battleAgent.UseWeapon(_aiEntity.WeaponSystem.EquippedWeapon.Id);

            // 射出火箭弹
            PbWeaponDataConfig weaponDataConfig = _aiEntity.WeaponSystem.EquippedWeapon.Config;
            if (weaponDataConfig != null)
            {
                PbWeaponBulletDataConfig weaponBulletDataConfig = LibertyConfigManager.GetInstance().GetWeaponBulletDataConfig(weaponDataConfig.bullet_id);
                if (weaponBulletDataConfig != null)
                {
                    Transform rocketTransform = LibertyPoolMgr.GetInstance().GetEffectObject(weaponBulletDataConfig.model);
                    rocketTransform.position = position;
                    rocketTransform.forward = direction;
                    BaseThrowable baseThrowable = rocketTransform.GetComponent<BaseThrowable>();
                    baseThrowable.InitBullet(weaponDataConfig, weaponBulletDataConfig, _aiEntity);
                    rocketTransform.SetActive(true);
                }
            }
        }
        
        /// <summary>
        /// 枪械重新装弹
        /// </summary>
        public void GunReload()
        {
            PbWeaponDataConfig weaponDataConfig = _aiEntity.WeaponSystem.HandleWeapon.Config;
            if (weaponDataConfig!=null)
            {
                ReloadWeapon(weaponDataConfig.weapon_id);
            }
            
            // 更新最后战斗状态的时间戳
            _aiEntity.viewer.animationAgent.UpdateLastBattleTimestamp();
        }
        
        /// <summary>
        /// 获取目标
        /// </summary>
        /// <param name="targetType"></param>
        /// <returns></returns>
        public AIEntity GetTarget(TargetType targetType)
        {
            AIEntity target = null;
            switch (targetType)
            {
                case TargetType.RevengeTarget:
                    target = revengeTarget;
                    break;
                
                case TargetType.CurrentLockTarget:
                    target = currentLockTarget;
                    break;
                
                case TargetType.PossibleTarget:
                    target = possibleTarget;
                    break;
                
                case TargetType.Self:
                    target = _aiEntity;
                    break;
                
                case TargetType.Player:
                    target = LibertyAIUtils.PlayerController.playerEntity.AIEntity;
                    break;
                case TargetType.ChaseRevengeTarget:
                    target = ChaseRevengeTarget;
                    break;
            }

            return target;
        }
        /// <summary>
        /// 设置目标
        /// </summary>
        /// <param name="targetType"></param>
        /// <param name="???"></param>
        /// <returns></returns>
        public void SetTarget(TargetType targetType, AIEntity target)
        {
            switch (targetType)
            {
                case TargetType.RevengeTarget:
                    revengeTarget = target;
                    break;
                
                case TargetType.CurrentLockTarget:
                    currentLockTarget = target;
                    break;
                
                case TargetType.PossibleTarget:
                    possibleTarget = target;
                    break;
                
                case TargetType.Self:
                    break;
                case TargetType.ChaseRevengeTarget:
                    ChaseRevengeTarget = target;
                    break;
            }
        }

        /// <summary>
        /// 受击
        /// </summary>
        /// <param name="attacker">攻击者</param>
        /// <param name="damageHp">伤害</param>
        /// <param name="animationState">被哪种攻击动作打中</param>
        public void OnHit(AIEntity attackerEntity, int damageHp, AnimationState animationState, bool hitHard,int weaponId)
        {
            if (!_aiData.isAlive)
            {
                return;
            }
            
            // 是否命中
            bool hasHitted = false;
            switch (animationState)
            {
                case AnimationState.BoxingAttackDown:
                case AnimationState.BoxingAttackKick:
                case AnimationState.BoxingCombo1:
                case AnimationState.BoxingCombo2:
                case AnimationState.BoxingCombo3:
                case AnimationState.HandGunBoxing:
                    {
                        // 近战不计算命中率
                        hasHitted = true;
                    }
                    break;

                default:
                    {
                        hasHitted = Random.Range(0, 100) <= attackerEntity.propertyDataConfig.hit_rate;
                    }
                    break;
            }
            if (!hasHitted)
            {
                return;
            }

            Transform attacker = attackerEntity.viewer.animator.transform;
            Transform defender = _aiEntity.viewer.animator.transform;

            // 飙血特效
            showOnHitEffect();
            
            // 被撞 TODO: 临时处理，不允许被撞的时候受击
            if (_aiData.npcStatus==NpcStatus.VehicleBarge || _aiData.animationState==AnimationState.BehaviourPuppet
                || _aiData.npcStatus==NpcStatus.EnterCar || _aiData.npcStatus==NpcStatus.InCar || _aiData.npcStatus==NpcStatus.ExitCar || _aiData.npcStatus==NpcStatus.ExpelCar)
            {
                return;
            }

            // 受击者音效
            switch (animationState)
            {
                case AnimationState.HandGunShoot:
                    {
                        // 被子弹击中没有受击音效
                    }
                    break;

                default:
                    {
                        // 默认受击音效
                        AudioManager.PlaySound(_aiEntity.propertyDataConfig.on_hit_audio, defender.gameObject);
                    }
                    break;
            }
   
            // 暴击双倍伤害
            if (hitHard)
            {
                damageHp *= 2;
            }
            // 扣血
            bool realHit = _aiData.ApplyDamage(damageHp);
            // 飘字
            if (realHit && _aiData.uniqueId!=LibertyAIUtils.PLAYER_AI_ID && attackerEntity.id==LibertyAIUtils.PLAYER_AI_ID)
            {
                if (Time.time >= _resetTotalDamageFromPlayerTimestamp)
                {
                    _totalDamageFromPlayer = 0;
                }
                _totalDamageFromPlayer += damageHp;
                _resetTotalDamageFromPlayerTimestamp = Time.time + 0.3f;
                
                showOnHitFlyText(_totalDamageFromPlayer, hitHard);
            }
            
            //伤害来源反馈
            if (realHit)
            {
                if (_aiData.uniqueId == LibertyAIUtils.PLAYER_AI_ID)
                {
                    var fromPos = attackerEntity.data.CurrentLerpPositin;
                    var myPos = _aiData.CurrentLerpPositin;
                    ResidentHandler.Inst.GetFunction("CityLuaFunction.OnHitDirection").Action(fromPos,myPos);
                }
            }
            // 仇恨目标
            revengeTarget = attackerEntity;
            // 被攻击的帧数
            _lastOnHitFrameCount = Time.frameCount;
            
            // 削韧值 (削韧超过角色韧性值，才可以触发受击动画)
            // bool canPlayHurtAnim = AddReduceToughness(reduceToughness);
            // 是否切到受击状态
            bool switchToOnHitStatus = true;

            if (_aiData.isAlive)
            {
                if (_aiData.animationState == AnimationState.OnHitDown
                    || _aiData.animationState == AnimationState.OnHitGetUp)
                {
                    // 受击方倒地状态下，不播放受击动画
                    // 倒下状态受击没有对应动画，手动播下受击音效
                    switch (animationState)
                    {
                        case AnimationState.BoxingCombo1:
                        case AnimationState.BoxingCombo2:
                        case AnimationState.BoxingCombo3:
                        case AnimationState.BoxingAttackKick:
                        case AnimationState.BoxingAttackDown:
                            {
                                // 近战音效
                                AudioManager.PlaySound(_BoxingOnHitSoundName, defender.gameObject);
                            }
                            break;
                    }
                }
                else
                {
                    // 播放受击动画
                    if (hitHard)
                    {
                        // 重击倒地
                        _aiEntity.viewer.animationAgent.PlayHurtBackDown();
                    }
                    else
                    {
                        // 非重击
                        switch (animationState)
                        {
                            case AnimationState.BoxingCombo1:
                                {
                                    _aiEntity.viewer.animationAgent.PlayHurtLeft();
                                }
                                break;
                            case AnimationState.BoxingCombo2:
                                {
                                    _aiEntity.viewer.animationAgent.PlayHurtRight();
                                }
                                break;
                            case AnimationState.BoxingCombo3:
                                {
                                    _aiEntity.viewer.animationAgent.PlayHurtBack();
                                }
                                break;
                            case AnimationState.BoxingAttackKick:
                                {
                                    _aiEntity.viewer.animationAgent.PlayHurtKick();
                                }
                                break;
                            case AnimationState.HandGunShoot:
                            case AnimationState.AutoRifleShoot:
                                {
                                    // 枪械射击
                                    if (_aiData.npcStatus == NpcStatus.Escape)
                                    {
                                        // 逃跑状态下不响应动画
                                        // 逃跑状态下不切状态
                                        switchToOnHitStatus = false;
                                    }
                                    else
                                    {
                                        int random = Random.Range(0, 2);
                                        switch (random)
                                        {
                                            case 0:
                                                {
                                                    _aiEntity.viewer.animationAgent.PlayHurtLeft();
                                                }
                                                break;
                                            case 1:
                                                {
                                                    _aiEntity.viewer.animationAgent.PlayHurtRight();
                                                }
                                                break;
                                        }
                                    }
                                }
                                break;
                            default:
                                {
                                    _aiEntity.viewer.animationAgent.PlayHurtBack();
                                }
                                break;
                        }
                    }
                }
                
            }
            else
            {
                // 死亡
                OnKill?.Invoke(_aiData.uniqueId, attackerEntity.id,weaponId);
                if (_aiData.uniqueId == LibertyAIUtils.PLAYER_AI_ID)
                {
                    ResidentHandler.Inst.GetFunction("CityLuaFunction.addStreetEventDeadCount").Action();
                }
                else
                {
                    if (attackerEntity.id == LibertyAIUtils.PLAYER_AI_ID)
                    {
                        ResidentHandler.Inst.GetFunction("CityLuaFunction.addStreetEventKillCount").Action();
                    }

                    if (attackerEntity.data.side == SideType.Player || attackerEntity.data.side == SideType.Teammate)
                    {
                        ResidentHandler.Inst.GetFunction("CityLuaFunction.addStreetEventTeamKillCount").Action();
                    }
                }
                // 死亡状态下不切状态
                switchToOnHitStatus = false;
                // 播放死亡动画
                _aiEntity.viewer.animationAgent.SetDisableOperate(true);
                // 去掉瞄准状态
                _aiEntity.viewer.animationAgent.EnterAimingState(AimingState.None);
                _aiEntity.viewer.animationAgent.PlayHurtBackDown();

                // 如果是npc，开始执行销毁流程
                if (_aiData.uniqueId != LibertyAIUtils.PLAYER_AI_ID)
                {
                    // 关闭伤害触发器
                    _aiEntity.onHitCollider.enabled = false;
                    _aiEntity.headCollider.enabled = false;
                    
                    // 死亡效果
                    showDeadEffect();
                }
                else
                {
                    // 玩家死亡，通知lua
                    ResidentHandler.Inst.GetFunction("CityLuaFunction.onHangingPlayerDead").Action();
                }
                
                // 玩家命中音效
                if (attackerEntity.id == LibertyAIUtils.PLAYER_AI_ID && _aiData.uniqueId != LibertyAIUtils.PLAYER_AI_ID)
                {
                    AudioManager.PlaySound("SandBox_Player2D_Fire_Kill");
                }
                
            }
            
            if (switchToOnHitStatus)
            {
                // 切换到受击状态
                _aiData.npcStatus = NpcStatus.OnHit;
            }

            // 玩家命中音效
            if (attackerEntity.id == LibertyAIUtils.PLAYER_AI_ID && _aiData.uniqueId != LibertyAIUtils.PLAYER_AI_ID)
            {
                AudioManager.PlaySound("SandBox_Player2D_Fire_Hit");
            }
            
            // 更新最后战斗状态的时间戳
            _aiEntity.viewer.animationAgent.UpdateLastBattleTimestamp();
        }
        
        /// <summary>
        /// 当前质量是否显示特效
        /// </summary>
        /// <returns></returns>
        bool isOpenEffect(bool isPlayerShow = false)
        {
            if (isPlayerShow)
            {
                return (int)QualityManager.Inst.CurrentQuality >= (int)_OpenEffectQuality || _aiData.uniqueId == LibertyAIUtils.PLAYER_AI_ID;
            }
            else
            {
                return (int)QualityManager.Inst.CurrentQuality >= (int)_OpenEffectQuality;
            }
        }

        // 死亡效果
        void showDeadEffect()
        {
            // // 2s后开启布娃娃
            // Timers.inst.Add(2f, 1, o =>
            // {
            //     if (!_aiEntity)
            //     {
            //         return;
            //     }
            //     
            //     if (_aiEntity.puppetMaster)
            //     {
            //         _aiEntity.puppetMaster.mode = PuppetMaster.Mode.Active;
            //         _aiEntity.puppetMaster.state = PuppetMaster.State.Dead;
            //     }
            // });
            // 2s后慢慢沉入地下
            Timers.inst.Add(2f, 1, _deadEffect1);
            // 5s后销毁
            Timers.inst.Add(5f, 1, _deadEffect2);
        }
        // 停止死亡效果
        void stopDeadEffect()
        {
            if (_DeadMoveYTween != null)
            {
                _DeadMoveYTween?.Kill();
                _DeadMoveYTween = null;
            }
            Timers.inst.Remove(_deadEffect1);
            Timers.inst.Remove(_deadEffect2);
        }
        
        TweenerCore<Vector3, Vector3, VectorOptions> _DeadMoveYTween = null;
        void _deadEffect1(object o)
        {
            if (!_aiEntity)
            {
                return;
            }
                      
            // 沉入地下的高度
            float downHeight = transform.position.y - 2;
            
            // 关闭碰撞 TODO: 
            _aiEntity.characterController.enabled = false;
            _aiEntity.seeker.LocomotionAgent.enabled = false;
            _aiEntity.puppetMaster.gameObject.SetActive(false);

            _DeadMoveYTween = _aiEntity.viewer.animator.transform.DOMoveY(downHeight, 2);
            _DeadMoveYTween.onComplete =() =>
            {
                _DeadMoveYTween = null;
            };
        }

        void _deadEffect2(object o)
        {
            if (!_aiEntity)
            {
                return;
            }

            // 销毁NPC
            if (_aiData.uniqueId != LibertyAIUtils.PLAYER_AI_ID)
            {
                LibertyAIUtils.AIManager.RemoveNpc(_aiData.uniqueId);
            }
        }
        
        void showOnHitEffect()
        {
            if (!isOpenEffect())
            {
                return;
            }
            
            Timers.inst.Remove(hideOnHitEffect);
            hideOnHitEffect(null);

            Transform defender = _aiEntity.viewer.animator.transform;
            _currentOnHitEffect = LibertyPoolMgr.GetInstance().GetEffectObject(_OnHitEffectResID);
            Transform upperChestBone = _aiEntity.viewer.animator.GetBoneTransform(HumanBodyBones.UpperChest);
            if (upperChestBone)
            {
                _currentOnHitEffect.transform.SetParent(upperChestBone);
                _currentOnHitEffect.transform.localPosition = Vector3.zero;
            }
            else
            {
                // Debug.LogError(LogModule.LibertySceneBattle, $"模型 {defender.name} 未找到UpperChest骨骼节点");
                _currentOnHitEffect.transform.SetParent(defender);
                _currentOnHitEffect.transform.localPosition = new Vector3(0, _aiEntity.characterController.height * 0.7f, 0);
            }
            _currentOnHitEffect.transform.localRotation = Quaternion.identity;
            _currentOnHitEffect.gameObject.SetActive(true);
            
            Timers.inst.Add(1f, 1, hideOnHitEffect);
        }
        void hideOnHitEffect(object o)
        {
            if (_currentOnHitEffect)
            {
                LibertyPoolMgr.GetInstance().RecycleEffect(_OnHitEffectResID, _currentOnHitEffect);
                _currentOnHitEffect = null;
            }
        }

        // 显示道具拾取特效
        public void ShowTakePropItemEffect(int effectID)
        {
            if (!isOpenEffect(true))
            {
                return;
            }
            
            hideTakePropItemEffect(null);
            Timers.inst.Remove(hideTakePropItemEffect);

            _currentTakePropItemEffectID = effectID;
            _currentTakePropItemEffect = LibertyPoolMgr.GetInstance().GetEffectObject(effectID);
            _currentTakePropItemEffect.SetParent(transform);
            _currentTakePropItemEffect.position = _aiEntity.viewer.animator.transform.position;// + (_aiEntity.characterController.height+0.5f)*Vector3.up;
            _currentTakePropItemEffect.gameObject.SetActive(true);

            Timers.inst.Add(1f, 1, hideTakePropItemEffect);
        }

        void hideTakePropItemEffect(object o)
        {
            if (_currentTakePropItemEffectID != 0)
            {
                LibertyPoolMgr.GetInstance().RecycleEffect(_currentTakePropItemEffectID, _currentTakePropItemEffect);
                _currentTakePropItemEffectID = 0;
                _currentTakePropItemEffect = null;
            }
        }

        void showOnHitFlyText(int damage, bool isCritical = false)
        {
            Timers.inst.Remove(hideOnHitFlyText);

            if (!_currentOnHitFlyText)
            {
                _currentOnHitFlyText = LibertyPoolMgr.GetInstance().GetEffectObject(_ScoreHudResID);
            }
            _currentOnHitFlyText.position = _aiEntity.viewer.animator.transform.position + (_aiEntity.characterController.height+0.5f)*Vector3.up;
            var streetScoreHud = _currentOnHitFlyText.GetComponent<StreetScoreHud>();
            streetScoreHud.SetMaterial(isCritical);
            streetScoreHud.SetText($"{damage}");
            _currentOnHitFlyText.gameObject.SetActive(true);

            Timers.inst.Add(1f, 1, hideOnHitFlyText);
        }

        void hideOnHitFlyText(object o)
        {
            if (_currentOnHitFlyText)
            {
                LibertyPoolMgr.GetInstance().RecycleEffect(_ScoreHudResID, _currentOnHitFlyText);
                _currentOnHitFlyText = null;
            }
        }


        public void OnGunHitPoint(Vector3 position, Vector3 normal)
        {
            
        }
        
        void showWeaponFireEffect()
        {
            if (!isOpenEffect(true))
            {
                return;
            }
            
            PbWeaponDataConfig weaponDataConfig = _aiEntity.WeaponSystem.HandleWeapon.Config;
            LibertyWeapon weapon = _aiEntity.weapon;
            
            // 武器特效
            if (weaponDataConfig.fire_effect_id > 0 && weapon)
            {
                Transform effect = LibertyPoolMgr.GetInstance().GetEffectObject(weaponDataConfig.fire_effect_id);
                // effect.SetParent(weapon.transform);
                if (weapon.MuzzleFlashPoint)
                {
                    effect.position = weapon.MuzzleFlashPoint.position;
                    effect.rotation = weapon.MuzzleFlashPoint.rotation;
                }
                else
                {
                    effect.position = weapon.transform.position;
                    effect.rotation = weapon.transform.rotation;
                }
                effect.SetActive(true);
                
                Timers.inst.Add(1f, 1, o =>
                {
                    if (_aiEntity == null)
                    {
                        return;
                    }
                    
                    LibertyPoolMgr.GetInstance().RecycleEffect(weaponDataConfig.fire_effect_id, effect);
                });
            }

        }

        // 武器弹道特效
        void showWeaponTrailEffect(Vector3 startPos, Vector3 endPos)
        {
            if (!isOpenEffect(true))
            {
                return;
            }
            
            PbWeaponDataConfig weaponDataConfig = _aiEntity.WeaponSystem.HandleWeapon.Config;;
            PbWeaponBulletDataConfig weaponBulletDataConfig = LibertyConfigManager.GetInstance().GetWeaponBulletDataConfig(weaponDataConfig.bullet_id);
            LibertyWeapon weapon = _aiEntity.weapon;
            
            // 弹道特效
            if (weaponBulletDataConfig!=null && weaponBulletDataConfig.trail_effect_id > 0 && weapon)
            {
                Transform effect = LibertyPoolMgr.GetInstance().GetEffectObject(weaponBulletDataConfig.trail_effect_id);
                effect.position = startPos;
                effect.forward = (endPos - startPos).normalized;
                effect.SetActive(true);

                Timers.inst.Add(0.1f, 1, o =>
                {
                    effect.position = endPos;
                });
                Timers.inst.Add(1f, 1, o =>
                {
                    if (_aiEntity == null)
                    {
                        return;
                    }
                    
                    LibertyPoolMgr.GetInstance().RecycleEffect(weaponBulletDataConfig.trail_effect_id, effect);
                });
            }
        }

        // 武器弹孔特效
        void showWeaponObstacleEffect(Vector3 position, Vector3 normal)
        {
            if (!isOpenEffect(true))
            {
                return;
            }
            
            PbWeaponDataConfig weaponDataConfig = _aiEntity.WeaponSystem.HandleWeapon.Config;;
            PbWeaponBulletDataConfig weaponBulletDataConfig = LibertyConfigManager.GetInstance().GetWeaponBulletDataConfig(weaponDataConfig.bullet_id);
            LibertyWeapon weapon = _aiEntity.weapon;
            
            // 弹道特效
            if (weaponBulletDataConfig!=null && weaponBulletDataConfig.obstacle_effect_id > 0 && weapon)
            {
                Transform effect = LibertyPoolMgr.GetInstance().GetEffectObject(weaponBulletDataConfig.obstacle_effect_id);
                effect.position = position + normal * _ObstacleOffset;  // 沿法线向上偏移
                effect.forward = normal;
                effect.SetActive(true);
                // Debug.LogError(LogModule.LibertySceneBattle, $"弹孔位置 ({effect.position.x}, {effect.position.y}, {effect.position.z})");

                Timers.inst.Add(2f, 1, o =>
                {
                    if (_aiEntity == null)
                    {
                        return;
                    }
                    
                    LibertyPoolMgr.GetInstance().RecycleEffect(weaponBulletDataConfig.obstacle_effect_id, effect);
                });
            }
        }
        
        private float FlashDuration = 5f;
        public float flashFrequency = 0.1f;
        private Renderer[] _renderers;
        private IEnumerator FlashCoroutine()
        {
            float timer = 0;
            bool isVisible = true;

            while (timer < FlashDuration)
            {
                foreach (var render in _renderers)
                {
                    // 切换可见性
                    if (render != null)
                    {
                        render.SetActive(isVisible);
                    }
                }
                isVisible = !isVisible;
                // 等待一段时间
                yield return new WaitForSeconds(flashFrequency);
                timer += flashFrequency;
            }
            foreach (var render in _renderers)
            {
                // 确保最后角色是可见的
                if (render != null)
                {
                    render.SetActive(true);
                }
            }
        }

        public void StartFlashing()
        {
            _renderers = transform.GetComponentsInChildren<Renderer>(true);
            StartCoroutine(FlashCoroutine());
        }
        
        public float detectionRadius = 8f; // 检测半径
        private int frameCount = 0; // 帧计数器
        private bool hasGrenade = false;
        private int grenadeNum = 0;
        private void UpdateGrenade()
        {
            if (_aiEntity.id == LibertyAIUtils.PLAYER_AI_ID)
            {
                // 每3帧检测一次
                if (frameCount == 3)
                {
                    // 在玩家周围的特定范围内检测碰撞体
                    grenadeNum = 0;
                    Collider[] hitColliders = Physics.OverlapSphere(transform.position, detectionRadius);
                    foreach (var hitCollider in hitColliders)
                    {
                        // 如果检测到手雷
                        var grenade = hitCollider.gameObject.GetComponent<Grenade>();
                        if (grenade != null)
                        {
                            hasGrenade = true;
                            grenadeNum++;
                            ResidentHandler.Inst.GetFunction("CityLuaFunction.OnGrenadeNearBody").Action(grenade.transform);
                        }
                    }

                    if (hasGrenade && grenadeNum == 0)
                    {
                        hasGrenade = false;
                        ResidentHandler.Inst.GetFunction("CityLuaFunction.OnGrenadeNearBody").Action();
                    }
                    // 重置帧计数器
                    frameCount = 0;
                }
                else
                {
                    // 增加帧计数器
                    frameCount++;
                }
            }
        }
        
        
    }
}
